<?php

$loader->requireOnce('ordo/TicketItem.class.php');
$loader->requireOnce('ordo/CompositeService.class.php');
$loader->requireOnce('ordo/Service.class.php');
$loader->requireOnce('ordo/QueueItem.class.php');

$loader->requireOnce('includes/CoreErrorCode.class.php');
$loader->requireOnce('includes/CoreException.class.php');
$loader->requireOnce('includes/LabConnector/LabAssignmentConnector.class.php');
$loader->requireOnce('includes/EnumerationConstant.class.php');
$loader->requireOnce('includes/RadConnector/RadAssignmentConnector.class.php');
$loader->requireOnce('includes/ParacliniqueEngine.class.php');
// TODO REVIEW 2009-09-17 ptnguyen
// Why is Insurance class loaded here?
// If we use Celini::newORDO('Insurance') => Do not need to include this class

// Fixed.
//$loader->requireOnce('ordo/Insurance.class.php');
$loader->requireOnce('includes/PatientQueue/AbsQueue.class.php');
$loader->requireOnce('includes/AjaxRender/TicketRender.class.php');

class C_Ticket extends Controller {
	var $template_mod;

	function C_Ticket($template_mod = "general") {
		parent::Controller();
		if (Celini::getCurrentController() == 'Ticket') {
			$menu =& Menu::getInstance();
			$menu->currentSection = 'patient';
		}
		$this->template_mod = $template_mod;
		$this->view->path = 'ticket';
		$this->logger = LoggerManager::getLogger('local.controllers.C_Ticket');
	}

	public function actionDisplayAjax() {
		$patientId = $_GET['patientId'];
		$departmentId = $this->_me->get_department_id();

		$this->ticketTree($patientId, false);
		$this->ticketTree($patientId, true);
		$this->patientInfo($patientId);

		$ticket = Celini::newORDO('Ticket');

		$ticketId = $ticket->isAnyOpenTicketByDepartment($patientId, $departmentId);
		//$ticketId = $ticket->isAnyOpenTicket($patientId);

		if ($ticketId !== false) {
			$ticket->setup($ticketId);
		}

		$this->assignCommonVariables($ticket);
		return $this->view->render('display.html');
	}

	public function actionAddAjax() {
		$patientId = $_GET['patient_id'];
		$ticket = Celini::newORDO('Ticket');
		$departmentId = $this->_me->get_department_id();
		$ticketId = $ticket->isAnyOpenTicketByDepartment($patientId, $departmentId);

		//$ticketId = $ticket->isAnyOpenTicket($patientId);
		if ($ticketId == false) {
			//add parameter patienttype
			$ticket->addNewTicket($patientId, $departmentId, EnumerationConstant::PATIENT_TYPE_OUTPATIENT);
			$ticketId = $ticket->get_id();
		} else {
			$ticket->setup($ticketId);
		}

		$result = array();
		$result['ticket_id'] = $ticketId;
		$result['ticket_name'] = $ticket->get('name');

		$this->assignTicketInfo($ticket);
		$this->patientInfo($patientId);
		$result['ticket_common_info'] = $this->view->render('ticket_common.html');
		return json_encode($result);
	}

    public function actionBuildLabAssignment4VEditAjax() {
        $result = array('error'=>array('code'=>CoreErrorCode::NORMAL,'mess'=>''),'result'=>'');
        $ticketId = $_GET['ticketId'];
        $labAssignmentTicketId = $_GET['labAssignmentTicketId'];
        $idOfActionAfterUpdating = $_GET['idOfActionAfterUpdating'];

        $this->logger->info('Start actionBuildLabAssignment4VEditAjax for patient has ticket ['. $ticketId .']');
       try {

            //$result['result'] = $this->tpProcessor->buildIPTestAssignDesktop($ticketId);
            $labAssignmentConnector = new LabAssignmentConnector();
            $result['result'] = $labAssignmentConnector->renderAssignmentPage4VEdit($ticketId, $labAssignmentTicketId, $idOfActionAfterUpdating);

        } catch (HISFileLoaderException $hisEx) {
            $result['error']['code'] = CoreErrorCode::LOAD_LAB_MODULE_FAIL;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::LOAD_LAB_MODULE_FAIL);
            $this->logger->error('actionBuildLabAssignment4VEditAjax for ticket [' . $ticketId . '] fail. Error detail: '. $hisEx->getMessage());


        } catch (EnumException $ex) {
            $result['error']['code'] = $ex->getErrorCode();
            $result['error']['mess'] = CoreErrorCode::getErrorMess($ex->getErrorCode());
            $this->logger->error('actionBuildLabAssignment4VEditAjax for ticket [' . $ticketId . '] fail. Error detail: '. $ex->getMessage());
        }
        $this->logger->info('Finish actionBuildLabAssignment4VEditAjax for patient has ticket ['. $ticketId .']');
        return json_encode($result);


    }

    public function actionLoadRadAssignmentEditAjax() {
        $result =   array('error' => array('code' => CoreErrorCode::NORMAL, 'mess' => ''), 'result' => '');
        $radType            =   $_GET['radType'];
        $radTicketId        =   $_GET['radTicketId'];
        $triggeredElement   =   $_GET['triggeredElement'];
        $this->logger->info("Start actionLoadRadAssignmentEditAjax {radTicketId=$radTicketId}");
       try {
            $radConnector = new RadAssignmentConnector();
            $result['result'] = $radConnector->loadAssignmentEdit($radType, $radTicketId, $triggeredElement);

        } catch (HISFileLoaderException $hisEx) {
            $result['error']['code'] = CoreErrorCode::LOAD_RAD_MODULE_FAIL;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::LOAD_RAD_MODULE_FAIL);
            $this->logger->error("Action LoadRadAssignmentEditAjax {radTicketId=$radTicketId} fail. Detail error: " . $hisEx->getMessage());
        } catch (EnumException $ex) {
            $result['error']['code'] = $ex->getErrorCode();
            $result['error']['mess'] = CoreErrorCode::getErrorMess($ex->getErrorCode());
            $this->logger->error("Action LoadRadAssignmentEditAjax {radTicketId=$radTicketId} fail. Detail error: " . $hisEx->getMessage());
        } catch (Exception $ex) {
            $result['error']['code'] = CoreErrorCode::COMMON_ERROR;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
            $this->logger->error("Action LoadRadAssignmentEditAjax {radTicketId=$radTicketId} fail. Detail error: " . $hisEx->getMessage());
        }
        $this->logger->info("Finish actionLoadRadAssignmentEditAjax {radTicketId=$radTicketId}");
        return json_encode($result);
    }

    /**
     * delete a test ticket.
     * @return unknown_type
     */
    public function actionDeleteLabAssignmentTicketAjax() {
        $result = array('error'=>array('code'=>CoreErrorCode::NORMAL,'mess'=>''),'result'=>array());
        $labAssignmentTicketId = $_GET['labAssignmentTicketId'];
        $this->logger->info('Start actionDeleteLabAssignmentTicketAjax [' . $labAssignmentTicketId . "]");
        try {


            $labAssignmentConnector = new LabAssignmentConnector();
            $deleteResult = $labAssignmentConnector->deleteAssignment($labAssignmentTicketId);

            if ($deleteResult['error']['code'] != CoreErrorCode::NORMAL) {
                $result['error']['code'] = $deleteResult['error']['code'];
                $result['error']['mess'] = $deleteResult['error']['mess'];
            } else {
                $result['result']= $deleteResult['result'];
            }

        } catch (HISFileLoaderException $hisEx) {
            $result['error']['code'] = CoreErrorCode::LOAD_LAB_MODULE_FAIL;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::LOAD_LAB_MODULE_FAIL);
            $this->logger->error('actionDeleteLabAssignmentTicketAjax fail. Error detail: '. $hisEx->getMessage());

        }
        $this->logger->info('Finish actionDeleteLabAssignmentTicketAjax [' . $labAssignmentTicketId . "]");
        return json_encode($result);
    }

    public function actionDeleteRadAssignmentTicketAjax() {
        $result = array('error'=>array('code'=>CoreErrorCode::NORMAL,'mess'=>''),'result'=>array());
        $radTicketId = $_GET['radTicketId'];
        $this->logger->info("Start action DeleteRadAssignmentTicketAjax {radTicketId=$radTicketId}");
        try {
            $radConnector = new RadAssignmentConnector();
            $deleteResult = $radConnector->deleteAssignmentTicket($radTicketId);

            if ($deleteResult['error']['code'] != CoreErrorCode::NORMAL) {
                $result['error']['code'] = $deleteResult['error']['code'];
                $result['error']['mess'] = $deleteResult['error']['mess'];
            } else {
                $result['result']= $deleteResult['result'];
            }

        } catch (HISFileLoaderException $hisEx) {
            $result['error']['code'] = CoreErrorCode::LOAD_RAD_MODULE_FAIL;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::LOAD_RAD_MODULE_FAIL);
            $this->logger->error('Action DeleteRadAssignmentTicketAjax fail. Error detail: '. $hisEx->getMessage());

        }
        $this->logger->info("Finish action DeleteRadAssignmentTicketAjax {radTicketId=$radTicketId}");
        return json_encode($result);
    }

	public function actionRenderParaclinicAssignmentAjax() {

		$ticketId = $_GET['ticket_id'];
		$enumParaClinic  = $_GET['enumParaClinic'];
		$result = array('error'=>array(
            'code'  =>  CoreErrorCode::NORMAL,'mess'=>''),
            'result'=>  ''
		);

		$this->logger->info('Start actionRenderParaclinicAssignmentAjax for patient has ticket ['. $ticketId .']');

		try {

			$ticket = Celini::newORDO('Ticket', $ticketId);
			if ($ticket->get('status') == Ticket::CLOSED_STATUS) {
				$result['error']['code'] = CoreErrorCode::CANNOT_ADD_PARACLINIC_TICKET_CLOSED;
				$result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::CANNOT_ADD_PARACLINIC_TICKET_CLOSED);
				return json_encode($result);
			}
			//Call requested connector
			switch ($enumParaClinic) {
				case Utils::getEnumKey(EnumerationConstant::PARACLINIC_TYPE, EnumerationConstant::PARACLINIC_LAB):
					//call lab assignment connector
					$labAssignmentConnector = new LabAssignmentConnector();
                    $result['result'] = $labAssignmentConnector->renderAssignmentPage($ticketId, 'refreshParaClinic');
                    break;
				case Utils::getEnumKey(EnumerationConstant::PARACLINIC_TYPE, EnumerationConstant::PARACLINIC_XRAY):
                case Utils::getEnumKey(EnumerationConstant::PARACLINIC_TYPE, EnumerationConstant::PARACLINIC_ENDO):
                case Utils::getEnumKey(EnumerationConstant::PARACLINIC_TYPE, EnumerationConstant::PARACLINIC_ULTRA):
                    $objConnector   =   new RadAssignmentConnector();
                    $html           =   $objConnector->loadAssignmentInputDetails($enumParaClinic, $ticketId, 'refreshParaClinic');
                    $result['result']   =  $html;
                    break;
				default:
					;
					break;
			}
		} catch (HISFileLoaderException $hisEx) {
            $result['error']['code'] = CoreErrorCode::LOAD_LAB_MODULE_FAIL;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::LOAD_LAB_MODULE_FAIL);
            $this->logger->error('actionRenderParaclinicAssignmentAjax for ticket [' . $ticketId . '] fail. Error detail: '. $hisEx->getMessage());


        } catch (EnumException $ex) {
            $result['error']['code'] = $ex->getErrorCode();
            $result['error']['mess'] = CoreErrorCode::getErrorMess($ex->getErrorCode());
            $this->logger->error('actionRenderParaclinicAssignmentAjax for ticket [' . $ticketId . '] fail. Error detail: '. $ex->getMessage());
        } catch (Exception $ex) {
        	$result['error']['code'] = CoreErrorCode::COMMON_ERROR;
            $result['error']['mess'] = CoreErrorCode::getErrorMess(CoreErrorCode::COMMON_ERROR);
            $this->logger->error('actionRenderParaclinicAssignmentAjax for ticket [' . $ticketId . '] fail. Error detail: '. $ex->getMessage());

        }
        $this->logger->info('Finish actionRenderParaclinicAssignmentAjax for patient has ticket ['. $ticketId .']');
		return json_encode($result);
	}


	public function actionCheckReadyToAddServiceAjax() {
		$ticketId = $_GET['ticket_id'];
		$servRoomId = $_GET['service_room_id'];

		$ticket = Celini::newORDO('Ticket', $ticketId);
		if ($ticket->get('status') == Ticket::CLOSED_STATUS) {
			return json_encode(array(
				'status'	=> 0,
				'body'		=> L10nHelper::_("Service ticket closed. Can not add more services.")));
		}

		// add a service to ticket
		$item = Celini::newORDO('TicketItem');
		$result = $item->checkServiceDuplicated($ticketId, $servRoomId);
		if ($result !== false) {
			return json_encode(array(
				'status'	=> 1,
				'body'		=> "<span class=\"impression\">" . L10nHelper::_("Notice:") . "</span> " . L10nHelper::_("Service ticket has existed") . " <span class=\"impression\">
				$result </span>"));
		}

		return json_encode(array(
				'status'	=> -1,
				'body'		=> ''));
	}

	public function actionCheckReadyToAddCompositeServiceAjax() {
		$ticketId = $_GET['ticket_id'];
		$compositeId = $_GET['composite_service_id'];

		$ticket = Celini::newORDO('Ticket', $ticketId);
		if ($ticket->get('status') == Ticket::CLOSED_STATUS) {
			return json_encode(array(
				'status'	=> 0,
				'body'		=> L10nHelper::_("Service ticket closed. Can not add more services.")));
		}

		// add a service to ticket
		$item = Celini::newORDO('TicketItem');
		$result = $item->checkCompositeDuplicated($ticketId, $compositeId);
		if ($result !== false) {
			return json_encode(array(
				'status'	=> 1,
				'body'		=> "<span class=\"impression\">" . L10nHelper::_("Notice:") . "</span> " . L10nHelper::_("Service ticket has existed") . " <span class=\"impression\">
				$result </span>"));
		}

		$csa = Celini::newORDO('CompositeServiceAsso');
		$items = $csa->getServiceInACompositeService($compositeId);
		$cs = Celini::newORDO('CompositeService', $compositeId);
		if (sizeof($items) == 0) {
			return json_encode(array(
				'status'	=> 2,
				'body'		=> L10nHelper::_("Group") . " <span class=\"impression\">".$cs->getLocalizedText('name')."</span> " . L10nHelper::_("There is not any service yet")));
		}
		return json_encode(array(
				'status'	=> -1,
				'body'		=> ''));
	}

	public function actionAddServiceAjax() {
		$ticketId = $_GET['ticket_id'];
		$servRoomId = $_GET['service_room_id'];

		// add a service to ticket
		$item = Celini::newORDO('TicketItem');
		$item->addService($ticketId, $servRoomId);
	}

	public function actionAddTestAjax() {
		$ticketId = $_GET['ticket_id'];
		$testItem = $_GET['test_item'];
		$testId = $_GET['test_id'];

		// add a test to ticket
		$item = Celini::newORDO('TicketItem');
		$item->addTest($ticketId, $testId, $testItem);
	}

	public function actionAppendPackageAjax() {
		$packageId = $_GET['package_id'];
		$ticketId = $_GET['ticket_id'];

		$ticket = Celini::newORDO('Ticket', $ticketId);
		if ($ticket->get('status') == Ticket::CLOSED_STATUS) {
			return 1;
		}

		$pi = Celini::newORDO('PackageItem');
		$items = $pi->getAllPackageItem($packageId);
		if (sizeof($items) == 0) {
			return 2;
		}

		$serviceItem = Celini::newORDO('PackageServiceItem');
		$testItem = Celini::newORDO('PackageTestItem');

		foreach ($items as $id=>$type) {
			$ti = Celini::newORDO('TicketItem');
			if ($type == PackageItem::TEST_TYPE) {
				$servOfTest = $testItem->getAllServiceOfTest($id);
				$testItem->setup($id);
				$ticketItemId = $ti->addTest($ticketId, $testItem->get('test_id'), $servOfTest);
			}
			else if ($type == PackageItem::SERVICE_TYPE) {
				$serviceItem->setup($id);
				$ticketItemId = $ti->addService($ticketId, $serviceItem->get('service_room_id'));
			}
		}

	}

	public function actionAddCompositeServiceAjax() {
		$compositeId = $_GET['composite_service_id'];
		$ticketId = $_GET['ticket_id'];

		// Add a composite service to the ticket
		$item = Celini::newORDO('TicketItem');
		$item->addCompositeService($ticketId, $compositeId);
	}

	public function actionUpdateCompositeServiceAjax() {
		$compositeId = $_GET['composite_service_id'];
		$ticketId = $_GET['ticket_id'];
		$compositeItem = $_GET['composite_service_item'];
		$ticketItemId = $_GET['ticket_item_id'];

		// add a composite service to ticket
		$item = Celini::newORDO('TicketItem');
		$item->updateCompositeService($ticketId, $ticketItemId, $compositeId, $compositeItem);
	}

	public function actionDeleteAjax() {
		$ticketId = $_GET['ticket_id'];
		$ticket = Celini::newORDO('Ticket', $ticketId);

		if ($ticket->isTicketInProgress($ticketId) === false) {
			$ticket->delete($ticketId);
			return true;
		}
		return $ticket->get('status');
	}

	public function actionViewOpenTicketAjax() {
		$ticketId = $_GET['ticket_id'];
		$ticketOrdo = Celini::newORDO('Ticket', $ticketId);
		$items = $ticketOrdo->getAllTicketItem($ticketId);

		$html = "";
		$columns = array('ordering', 'service_name', 'room_name', 'patient_price',
						'discount', 'payment_type', 'status', 'cancel_button');
		$user = Celini::newORDO('User');
		$userRole = $user->getRole($this->_me->get_username());
		foreach ($items as $ticketItemId=>$type){
			switch ($type) {
				case TicketItem::SERVICE_TYPE:
					$html .= TicketRender::renderHTMLServiceItem($ticketItemId, $columns, $userRole);
					break;
				case TicketItem::TEST_TYPE:
					$html .= TicketRender::renderHTMLLabItem($ticketItemId, $columns, $userRole);
					break;
				case TicketItem::COMPOSITE_SERVICE:
					$html .= TicketRender::renderHTMLCompositeItem($ticketItemId, $columns, $userRole);
					break;
                case TicketItem::XRAY_TYPE:
                case TicketItem::ENDO_TYPE:
                case TicketItem::ULTRA_TYPE:
                	$html .= TicketRender::renderHTMLRadItem($ticketItemId, $columns, $userRole);
                    break;
                default:
                	break;
			}
		}
		$name = $ticketOrdo->get('name');

		$result['ticket_name'] = $name;
		$result['ticket_body'] = $html;
		return json_encode($result);
	}

	public function actionViewCloseTicketAjax() {
		$ticketId = $_GET['ticket_id'];
		$ticketOrdo = Celini::newORDO('Ticket');
		$items = $ticketOrdo->getAllTicketItem($ticketId);
		$patientId = $_GET['patient_id'];
		$insurance = Celini::newORDO('Insurance')->insuranceType($patientId);
		$html = "";
		$columns = array('service_name', 'room_name', 'patient_price', 'discount');
		foreach ($items as $ticketItemId=>$type){
			if ($type == TicketItem::SERVICE_TYPE) {
				$html .= TicketRender::renderHTMLClosedServiceItem($ticketItemId, $columns);
			} else if ($type == TicketItem::TEST_TYPE) {
				$html .= TicketRender::renderHTMLClosedTestItem($ticketItemId, $columns);
			} else if ($type == TicketItem::COMPOSITE_SERVICE) {
				$html .= TicketRender::renderHTMLCompositeItem($ticketItemId, $columns, Ticket::CLOSED_STATUS);
			}
		}
		$result = array();
		$ticketOrdo->setup($ticketId);
		$result['ticket']['name'] = $ticketOrdo->get('name');
		$result['ticket']['discount_program'] = $ticketOrdo->getDiscountProgramName($ticketId);
		$result['ticket']['examination_type'] = $ticketOrdo->getExaminationTypeName($ticketId);
		$result['ticket']['date'] = L10nHelper::renderDateTime($ticketOrdo->get('created'));
		$result['ticket']['body'] = $html;
		$result['ticket']['insurance'] = $insurance;

		$result['modification']['status'] = false;
		if ($ticketOrdo->get('modifier_id') != '' && $ticketOrdo->get('modifier_id') != 0) {
			$result['modification']['status'] = true;
			$person = Celini::newORDO('Person');
			if ($ticketOrdo->get('modifier_id') == -1) {
				$name = 'admin';
			} else {
				$person->setup($ticketOrdo->get('modifier_id'));
				$name = $person->get('name');
			}
			$result['modification']['modifierName'] = $name;
			$result['modification']['modifiedDate'] = L10nHelper::renderDateTime($ticketOrdo->get('modified_date'));
		}

		$result['payment'] = array (
			'total_price' 		=> L10nHelper::renderCurrency($ticketOrdo->get('patient_payment_without_discount')),
			'patient_price'		=> L10nHelper::renderCurrency($ticketOrdo->get('patient_payment')),
			'real_price'		=> L10nHelper::renderCurrency($ticketOrdo->get('real_payment')),
			'discount_price'	=> L10nHelper::renderCurrency($ticketOrdo->get('discount_payment'))
		);

		return json_encode($result);
	}

	public function actionSaleProgramChange() {
		$saleId = $_GET['sale_id'];

		$saleOrdo = Celini::newORDO('SaleProgram', $saleId);
		$saleStore = Celini::newORDO('SaleProgramStore');
		$saleProgramStoreId = $saleStore->getProgramStoreOfSale($saleId);

		$result = array('code' => $saleOrdo->get('code'),
					'name' => $saleOrdo->get('name'),
					'saleProgramStoreId' => $saleProgramStoreId);
		return json_encode($result);
	}

	public function actionUpdateCommonInfoAjax() {
		$this->performUpdateCommonInfo(
		$_POST['ticket_id'],
		$_POST['sale_program_store_id'],
		$_POST['insurance'],
		$_POST['examination_type_id'],
		$_POST['ticket_note']);

		return $this->view->render('ticket_common.html');
	}

	public function actionUpdateCommonInfoFromCashierAjax() {
		$this->performUpdateCommonInfo(
		$_POST['ticket_id'],
		$_POST['sale_program_store_id'],
		$_POST['insurance'],
		$_POST['examination_type_id'],
		$_POST['ticket_note']);

		return $this->view->render('ticket_common_cashier.html');
	}

	private function performUpdateCommonInfo($ticketId, $saleProgramStoreId,
	$insurance, $examinationTypeId, $ticketNote = false, $examCause = false) {
		if (empty($saleProgramStoreId)) {
			$saleProgramStoreId = 0;
		}
		if ($insurance == 'true') {
			$patientId = Celini::newORDO('Ticket', $ticketId)->get('patient_id');
			$insurance = Celini::newORDO('Insurance')->insuranceType($patientId);
		} else {
			$insurance = 'no';
		}

		$ticket = Celini::newORDO('Ticket');
		$ticket->updateCommonInfo($ticketId, $insurance,
		$saleProgramStoreId, $examinationTypeId,
		$examCause, $ticketNote);

		$ticket->setup($ticketId);
		$this->assignTicketInfo($ticket);
		$this->patientInfo($ticket->get('patient_id'));
	}

	public function actionTurnDownAjax() {
		$ticketItemId = $_GET['ticket_item_id'];
		$ti = Celini::newORDO('TicketItem', $ticketItemId);
		if ($ti->get('status') == TicketItem::CLOSED) {
			return 2;
		} else if ($ti->preCheckOrdering(false)) {
			return 1;
		}
		$ti->turnDown();
		return 0;
	}

	public function actionTurnUpAjax() {
		$ticketItemId = $_GET['ticket_item_id'];
		$ti = Celini::newORDO('TicketItem', $ticketItemId);

		$res = $ti->getItemByOrder($ti->get('ticket_id'), $ti->get('item_order') - 1);
		if ($res !== false && Celini::newORDO('TicketItem', $res)->get('status') == TicketItem::CLOSED) {
			return 2;
		} else if ($ti->preCheckOrdering(true)) {
			return 1;
		}
		$ti->turnUp();
		return 0;
	}

	public function actionSubmitTurning() {
		$ticketItemId = $_GET['ticket_item_id'];
		$dortorId = $_GET['doctor_id'];
		$direction = $_GET['direction'];

		$ti = ORDataObject::factory('TicketItem');
		$ti->setup($ticketItemId);
		$ticketId = $ti->get('ticket_id');
		$order = $ti->get('item_order');
		if ($direction == 'up') {
			$inProgressItem = $ti->getItemByOrder($ticketId, $order - 1);
			$nextItem = $ticketItemId;
			$ti->turnUp();
		} else if ($direction == 'down') {
			$inProgressItem = $ticketItemId;
			$nextItem = $ti->getItemByOrder($ticketId, $order + 1);
			$ti->turnDown();
		}

		$ti->setup($inProgressItem);
		$ti->populateArray(array('status' => TicketItem::OPEN));
		$ti->persist();

		$ti->setup($nextItem);
		$ti->populateArray(array('status' => TicketItem::IN_PROGRESS,
								'doctor_id' => $dortorId));
		$ti->persist();

		AbsQueue::removeTicketItem($inProgressItem);
		$queue = AbsQueue::getQueue(AbsQueue::IN_PROGRESS);
		$queue->addTicketItem($nextItem);
		$qi = QueueItem::fromTicketItemId($nextItem);
		$qi->set('holder_id', $dortorId);
		$qi->persist();
	}

	public function actionGetDoctorList() {
		$doctorList = Celini::newORDO('Employee')->getDoctorList();
		$currentDoctor = $this->_me->get_person_id();
		$text = "<select id='doctorList'>";
		foreach ($doctorList as $id=>$name) {
			if ($id == $currentDoctor) {
				$text .= "<option value='$id' label='$name' selected='selected'>$name</option>";
			} else {
				$text .= "<option value='$id' label='$name'>$name</option>";
			}
		}
		$text .= "</select>";
		return $text;
	}


	public function actionInitializingTicketAjax() {
		$ticketId = $_GET['ticket_id'];
		$patientId = $_GET['patient_id'];

		// get first open ticketItem in the current ticket
		$ticket = Celini::newORDO('Ticket', $ticketId);

		// If ticket was closed, return
		if ($ticket->get('status') == Ticket::CLOSED_STATUS) {
			return json_encode(array('status' => "closed", 'message' => L10nHelper::_("Service ticket closed.")));
		}

		// start only one time, it affects the simple statistic
		if ($ticket->get('started') == '0000-00-00 00:00:00') {
			$ticket->start($ticketId);
		}

		// add patient to patient_entry table
		// 1. get receptionist name
		// 2. insert into patient_entry
		$receptId = $this->_me->get_user_id();
		$personId = Base_User::fromId($receptId)->get('person_id');
		$receptName = Celini::newORDO('Person', $personId)->get('name');
		Celini::newORDO('PatientEntry')->add($ticketId, $patientId, $receptName);


		$firstOpenTicketItemId = $ticket->getFirstTicketItem($ticketId, TicketItem::OPEN);
		$firstInProgressTicketItemId = $ticket->getFirstTicketItem($ticketId, TicketItem::IN_PROGRESS);
		$firstWaitingTicketItemId = $ticket->getFirstTicketItem($ticketId, TicketItem::WAITING);

		// check payment type
		$ticketItem = Celini::newORDO('TicketItem', $firstOpenTicketItemId);

		$ticketItemInQueue = 0;
		// IF NOT found any OPEN-ticketItem
		// Get the last ticketItem and move it to the cashier queue
		if ($firstOpenTicketItemId === false
		&& $firstInProgressTicketItemId === false && $firstWaitingTicketItemId === false) {

			$ticketItemInQueue = $ticket->getLastTicketItem($ticketId);
			AbsQueue::moveTicketItemToQueue($ticketItemInQueue, AbsQueue::CASHIER);
		}
		// IN_PROGRESS Ticket has highest priority, then OPEN and the last is WAITING
		else if ($firstInProgressTicketItemId !== false) {

			$ticketItemInQueue = $firstInProgressTicketItemId;
		}

		else if ($firstOpenTicketItemId !== false) {

			$ticketItemInQueue = $firstOpenTicketItemId;

			if ($ticketItem->isPaymentType($firstOpenTicketItemId, Service::BEFORE) == true) {
				// Add this ticket item to Cashier queue

				$queue = AbsQueue::getQueue(AbsQueue::CASHIER);
				$queue->addTicketItem($firstOpenTicketItemId);
			}
			else {
				// Add this ticket item to Encounter queue
				$queue = AbsQueue::getQueue(AbsQueue::ENCOUNTER);
				$queue->addTicketItem($firstOpenTicketItemId);

				//start paraclinic assignment if it's paraclinic item
                // added by Viet Hoang
                $queueItem = QueueItem::fromTicketItemId($firstOpenTicketItemId);
                ParacliniqueEngine::startParaClinicTicket($firstOpenTicketItemId,$queueItem->get('room_id'));
			}
		}

		else if ($firstWaitingTicketItemId !== false) {
			$ticketItemInQueue = $firstWaitingTicketItemId;
		}

		$queueItem = QueueItem::fromTicketItemId($ticketItemInQueue);
		$room = Celini::newORDO('Room', $queueItem->get('room_id'));
		$roomName = $room->getLocalizedText('name');

		$redirectLink = Celini::link('renderQueue', 'Queue');
		// response to client
		return json_encode(array(
			'status' => "open",
			'message' => $roomName,
			'redirectLink'	=> $redirectLink));
	}

	public function actionUpdateNewFeeAjax() {
		$ticketItemObj = Celini::newORDO('TicketItem');
		$ticketItem = $ticketItemObj->getServiceItem($_POST['itemId']);
		Celini::newORDO('TicketItem')->updateNewFee($_POST['itemId'], $_POST['newFee']);
		TrackingSystemManagement::trackChanging($this->_me->get_user_id(),
		EnumerationConstant::TRACKING_SYSTEM_CHANGEFEE, $ticketItemObj->_table, $_POST['itemId'],
		$ticketItem['patient_price'], $_POST['newFee'], $_POST['reason']);
	}

	////////////////// PRIVATE METHODS ///////////////////////

	private function assignCommonVariables($ticket) {
		$this->assignTicketInfo($ticket);

		$userRole = $this->_me->get_role();
		$login2Dept = $this->_me->get_department_id();
		$this->assign('userRole', $userRole);

		$dept = Celini::newORDO('Department')->getDepartment($login2Dept);
		$this->assign('departments', array($login2Dept =>$dept['name']));

		$composite = Celini::newORDO('CompositeService');
		$compositeServiceList = $composite->listAll();
		$this->assign('compositeServiceList', $compositeServiceList);
		/*
		$test = Celini::newORDO('Test');
		$testList = $test->listAll();
		$this->assign('testList', $testList);
		*/
		$paraClinicServices = Utils::getEnumArrayKey(EnumerationConstant::PARACLINIC_TYPE);
		$this->assign('paraClinicServices', $paraClinicServices);

	}

	private function assignTicketInfo($ticket) {
		$this->assign_by_ref('ticket', $ticket);

		$saleOrdo = Celini::newORDO('SaleProgram');
		$this->assign('saleProgram', $saleOrdo->getCurrentSaleProgramsForOption());
		$saleId = $ticket->getSaleProgramId($ticket->get_id());
		$saleOrdo->setup($saleId);
		$this->assign_by_ref('sale', $saleOrdo);

		$examOrdo = Celini::newORDO('ExaminationType');
		$this->assign('examinationType', $examOrdo->getAllItems());
		$name = Celini::newORDO('ExaminationType', $ticket->get('examination_type_id'))->getLocalizedText('name');
		$this->assign('examinationTypeName', $name);

		$user = Celini::newORDO('User');
		$userRole = $user->getRole($this->_me->get_username());
		$this->assign('userRole', $userRole);
	}

	private function ticketTree($patientId, $status) {
		$ticket = Celini::newORDO('Ticket');
		$departmentId = $this->_me->get_department_id();
		$res = $ticket->getAllTicketOfPatientByDepartment($patientId, $departmentId, $status);
		//$res = $ticket->getAllTicketOfPatient($patientId, $status);
		$ticketTree = array();
		foreach ($res as $ticket) {
			$name = $ticket['name'];
			$id = $ticket['ticket_id'];
			$ticketTree[] = array('ticket_id' => $id, 'name' => $name);
		}
		if (sizeof($ticketTree) > 0) {
			if ($status) {
				// only one open ticket available in the system for one patient
				$this->assign('newTicket', $ticketTree[0]);
			} else {
				$this->assign('ticketTree', $ticketTree);
			}
		}
	}

	private function patientInfo($patientId) {
		$this->assign('patientId', $patientId);
		$insuranceType = Celini::newORDO('Insurance')->insuranceType($patientId);
		$this->assign('insuranceType', $insuranceType);
	}

}
?>